Skip to content

Connectors: Add is_active callback support to plugin registration#11565

Closed
Adi-ty wants to merge 5 commits intoWordPress:trunkfrom
Adi-ty:backport/connector-is-active-callback
Closed

Connectors: Add is_active callback support to plugin registration#11565
Adi-ty wants to merge 5 commits intoWordPress:trunkfrom
Adi-ty:backport/connector-is-active-callback

Conversation

@Adi-ty
Copy link
Copy Markdown

@Adi-ty Adi-ty commented Apr 13, 2026

Backport of WordPress/gutenberg#76994. Adds an optional is_active callable to the plugin definition when
registering a connector via WP_Connector_Registry::register().

The Connectors screen previously resolved a connector's active/installed status by checking is_plugin_active() and file_exists() against WP_PLUGIN_DIR only. Plugins installed as must-use plugins — or loaded from non-standard paths could not be detected this way, causing their connectors to disappear from the screen even though the plugin was in use.

Trac ticket: https://core.trac.wordpress.org/ticket/65020


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@github-actions
Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@Adi-ty Adi-ty marked this pull request as ready for review April 14, 2026 05:45
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 14, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props iamadisingh, jorgefilipecosta, mukesh27, gziolo.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Comment thread src/wp-includes/class-wp-connector-registry.php
Comment thread src/wp-includes/connectors.php Outdated
@Adi-ty Adi-ty requested a review from mukeshpanchal27 April 20, 2026 07:15
@Adi-ty Adi-ty force-pushed the backport/connector-is-active-callback branch from 6377fdc to 341e216 Compare April 21, 2026 09:49
@gziolo
Copy link
Copy Markdown
Member

gziolo commented Apr 27, 2026

Can you add an unit test that covers this new option? This would be similar to:

/**
* @ticket 64791
*/
public function test_register_includes_plugin_data() {
$args = self::$default_args;
$args['plugin'] = array( 'file' => 'my-plugin/my-plugin.php' );
$result = $this->registry->register( 'with-plugin', $args );
$this->assertArrayHasKey( 'plugin', $result );
$this->assertSame( array( 'file' => 'my-plugin/my-plugin.php' ), $result['plugin'] );
}

In particular it would be useful to cover the path when is_active doesn't have callable type.

Otherwise, this looks to go and should be included in WordPress 7.0 release.

Comment thread src/wp-includes/connectors.php Outdated
$is_installed = file_exists( wp_normalize_path( WP_PLUGIN_DIR . '/' . $file ) );
$is_activated = $is_installed && is_plugin_active( $file );
$is_activated = (bool) call_user_func( $connector_data['plugin']['is_active'] );
$is_installed = $is_activated || file_exists( WP_PLUGIN_DIR . '/' . $file );
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two notes:

  • the default is_active call is __return_true which always returns true, so when not defined, it will always assume the plugin is installed
  • file_exists no longer normalizes the path

@gziolo
Copy link
Copy Markdown
Member

gziolo commented Apr 28, 2026

Some additional feedback to evaluate. The rest looks good to me. I would appreciate confirmation from @jorgefilipecosta, too.

@jorgefilipecosta jorgefilipecosta force-pushed the backport/connector-is-active-callback branch from 598847d to 31eb00b Compare April 30, 2026 10:51
@jorgefilipecosta
Copy link
Copy Markdown
Member

Hi @gziolo I pushed a commit addressing your feedback and passing an is_active callback for the ai providers.

}
}

if ( ! isset( $args['plugin']['is_active'] ) ) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That one is very important 👍🏻

pento pushed a commit that referenced this pull request Apr 30, 2026
Adds an optional `is_active` callable to the `plugin` definition accepted by
`WP_Connector_Registry::register()`. The callback receives no arguments, must
return a boolean, and is used by the Connectors screen to decide whether a
connector's backing plugin is currently active. When omitted, it defaults to
`__return_true`; when provided but not callable, registration fails with a
`_doing_it_wrong()` notice.

Developed in: #11565

Props iamadisingh, jorgefilipecosta, mukesh27, gziolo.
Fixes #65020.

git-svn-id: https://develop.svn.wordpress.org/trunk@62288 602fd350-edb4-49c9-b593-d223f7449a82
@github-actions
Copy link
Copy Markdown

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 62288
GitHub commit: b3b40be

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions Bot closed this Apr 30, 2026
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Apr 30, 2026
Adds an optional `is_active` callable to the `plugin` definition accepted by
`WP_Connector_Registry::register()`. The callback receives no arguments, must
return a boolean, and is used by the Connectors screen to decide whether a
connector's backing plugin is currently active. When omitted, it defaults to
`__return_true`; when provided but not callable, registration fails with a
`_doing_it_wrong()` notice.

Developed in: WordPress/wordpress-develop#11565

Props iamadisingh, jorgefilipecosta, mukesh27, gziolo.
Fixes #65020.
Built from https://develop.svn.wordpress.org/trunk@62288


git-svn-id: http://core.svn.wordpress.org/trunk@61568 1a063a9b-81f0-0310-95a4-ce76da25c4cd
pento pushed a commit that referenced this pull request May 6, 2026
Adds an optional `is_active` callable to the `plugin` definition accepted by `WP_Connector_Registry::register()`. The callback receives no arguments, must return a boolean, and is used by the Connectors screen to decide whether a connector's backing plugin is currently active. When omitted, it defaults to `__return_true`; when provided but not callable, registration fails with a `_doing_it_wrong()` notice.

Developed in: #11565

Reviewed by desrosj.
Merges [62288] to the 7.0 branch.

Props iamadisingh, jorgefilipecosta, mukesh27, gziolo, desrosj.
Fixes #65020.

git-svn-id: https://develop.svn.wordpress.org/branches/7.0@62309 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request May 6, 2026
Adds an optional `is_active` callable to the `plugin` definition accepted by `WP_Connector_Registry::register()`. The callback receives no arguments, must return a boolean, and is used by the Connectors screen to decide whether a connector's backing plugin is currently active. When omitted, it defaults to `__return_true`; when provided but not callable, registration fails with a `_doing_it_wrong()` notice.

Developed in: WordPress/wordpress-develop#11565

Reviewed by desrosj.
Merges [62288] to the 7.0 branch.

Props iamadisingh, jorgefilipecosta, mukesh27, gziolo, desrosj.
Fixes #65020.
Built from https://develop.svn.wordpress.org/branches/7.0@62309


git-svn-id: http://core.svn.wordpress.org/branches/7.0@61589 1a063a9b-81f0-0310-95a4-ce76da25c4cd
t-hamano added a commit to WordPress/gutenberg that referenced this pull request May 7, 2026
…7897)

* Connectors: Add is_active callback support to plugin registration

Backports the WP Core changes from WordPress/wordpress-develop#11565
so that AI provider connectors (and Akismet) report the correct plugin
status. Without an explicit `is_active` callback the registry's new
`__return_true` default made every pre-registered connector appear active
even when the underlying plugin was not installed, so the Connectors
screen showed a "Set up" button instead of "Install" whenever Gutenberg
was active.

- Mirror the registry's `__return_true` default and the simplified
  is_installed/is_activated derivation in the script module data.
- Wire AI providers to `$ai_registry->hasProvider( $id )` so their
  status reflects whether the provider plugin is actually available.
- Set Akismet's `is_active` to `is_plugin_active( 'akismet/akismet.php' )`
  since Gutenberg pre-registers it (Core does not), and the new default
  would otherwise mark it as always installed.

* Connectors: Show Akismet with Install button when not installed

The previous client-side workaround hid Akismet entirely whenever the
plugin was not installed, because the server could not report Akismet's
install status reliably. With the new `is_active` callback wired up on
the server side, `isInstalled` is now accurate, so Akismet can be
rendered like any other default connector and offer an Install button
when the plugin is missing.

* Connectors: Restore E2E coverage for Akismet Install button

Re-adds the test that was removed when Akismet was hidden client-side
in #76962. Now that the server reports Akismet's install status
correctly and the JS hide logic is gone, the screen should render the
Akismet card with an Install button when the plugin is not installed —
make sure that's covered.

* Connectors: Update E2E test to expect Install button label

* Connectors: Drop default is_active fallback in registry

All pre-registered connectors now supply their own `is_active` callback,
so the `__return_true` default is no longer needed. Removing it aligns
the registry with the upstream WP Core PR and avoids silently masking
connectors that forget to declare an `is_active` callback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Guard against missing is_active in script module data

Now that the registry no longer injects a default `__return_true` for
`is_active`, a connector registered with a `plugin.file` but without an
`is_active` callback would trigger an undefined-index warning. Treat
that case as active on the assumption the plugin only registers the
connector when it is loaded.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Detect Akismet via AKISMET_VERSION constant

Switch the Akismet `is_active` callback from `is_plugin_active()` to a
`defined( 'AKISMET_VERSION' )` check so it does not have to load
`wp-admin/includes/plugin.php`. This keeps the callback safe to invoke
in non-admin requests where pulling in the admin plugin helpers would
be unnecessary overhead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ADd backport changelog

* Connectors: Remove outdated is_active default from docblock

The default `__return_true` fallback was dropped from the registry, but
the docblock still advertised it. Remove the stale line so callers do
not assume a default exists.

* Connectors: Restore Akismet hide-when-not-installed special case

Bring back the JS-side guard that hides Akismet when the plugin is not
installed. Akismet is bundled with WordPress and the product decision
is to keep it out of the connectors list when missing — other connectors
remain visible because plugins like Woo or SEO suites benefit from the
auto-install/activate flow for their own third-party integrations.

Also drop the E2E test that asserted the inverse (Install button visible
for Akismet), since it conflicts with the restored behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Document default is_active behavior in docblock

When the is_active callback is omitted and a file is provided, the
connector is treated as active under the assumption that the plugin
must be loaded in order to register itself. Spell that out so callers
do not mistake the omission for a no-op.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Use validate_plugin() to detect installed plugin file

Switch the install probe from a raw file_exists() to validate_plugin(),
which adds path traversal protection and confirms the file is a
recognised plugin (not just any file at that path). Restores the
require_once for wp-admin/includes/plugin.php that this function needs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Default plugin is_active to __return_true

Align with WordPress core, which sets is_active to '__return_true' when
omitted at registration. This lets the rendering site call is_active
unconditionally instead of branching on whether it was provided.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Align phpstan type with stored connector shape

After the registry now always initializes `plugin` and defaults
`is_active` to `__return_true`, mark `plugin` as required and
`file` as optional in the @phpstan-type so static analysis matches
what `register()` actually returns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: peterwilsoncc <peterwilsoncc@git.wordpress.org>
Co-authored-by: mukeshpanchal27 <mukesh27@git.wordpress.org>
Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org>
Co-authored-by: westonruter <westonruter@git.wordpress.org>
gutenbergplugin pushed a commit to WordPress/gutenberg that referenced this pull request May 7, 2026
…7897)

* Connectors: Add is_active callback support to plugin registration

Backports the WP Core changes from WordPress/wordpress-develop#11565
so that AI provider connectors (and Akismet) report the correct plugin
status. Without an explicit `is_active` callback the registry's new
`__return_true` default made every pre-registered connector appear active
even when the underlying plugin was not installed, so the Connectors
screen showed a "Set up" button instead of "Install" whenever Gutenberg
was active.

- Mirror the registry's `__return_true` default and the simplified
  is_installed/is_activated derivation in the script module data.
- Wire AI providers to `$ai_registry->hasProvider( $id )` so their
  status reflects whether the provider plugin is actually available.
- Set Akismet's `is_active` to `is_plugin_active( 'akismet/akismet.php' )`
  since Gutenberg pre-registers it (Core does not), and the new default
  would otherwise mark it as always installed.

* Connectors: Show Akismet with Install button when not installed

The previous client-side workaround hid Akismet entirely whenever the
plugin was not installed, because the server could not report Akismet's
install status reliably. With the new `is_active` callback wired up on
the server side, `isInstalled` is now accurate, so Akismet can be
rendered like any other default connector and offer an Install button
when the plugin is missing.

* Connectors: Restore E2E coverage for Akismet Install button

Re-adds the test that was removed when Akismet was hidden client-side
in #76962. Now that the server reports Akismet's install status
correctly and the JS hide logic is gone, the screen should render the
Akismet card with an Install button when the plugin is not installed —
make sure that's covered.

* Connectors: Update E2E test to expect Install button label

* Connectors: Drop default is_active fallback in registry

All pre-registered connectors now supply their own `is_active` callback,
so the `__return_true` default is no longer needed. Removing it aligns
the registry with the upstream WP Core PR and avoids silently masking
connectors that forget to declare an `is_active` callback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Guard against missing is_active in script module data

Now that the registry no longer injects a default `__return_true` for
`is_active`, a connector registered with a `plugin.file` but without an
`is_active` callback would trigger an undefined-index warning. Treat
that case as active on the assumption the plugin only registers the
connector when it is loaded.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Detect Akismet via AKISMET_VERSION constant

Switch the Akismet `is_active` callback from `is_plugin_active()` to a
`defined( 'AKISMET_VERSION' )` check so it does not have to load
`wp-admin/includes/plugin.php`. This keeps the callback safe to invoke
in non-admin requests where pulling in the admin plugin helpers would
be unnecessary overhead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ADd backport changelog

* Connectors: Remove outdated is_active default from docblock

The default `__return_true` fallback was dropped from the registry, but
the docblock still advertised it. Remove the stale line so callers do
not assume a default exists.

* Connectors: Restore Akismet hide-when-not-installed special case

Bring back the JS-side guard that hides Akismet when the plugin is not
installed. Akismet is bundled with WordPress and the product decision
is to keep it out of the connectors list when missing — other connectors
remain visible because plugins like Woo or SEO suites benefit from the
auto-install/activate flow for their own third-party integrations.

Also drop the E2E test that asserted the inverse (Install button visible
for Akismet), since it conflicts with the restored behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Document default is_active behavior in docblock

When the is_active callback is omitted and a file is provided, the
connector is treated as active under the assumption that the plugin
must be loaded in order to register itself. Spell that out so callers
do not mistake the omission for a no-op.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Use validate_plugin() to detect installed plugin file

Switch the install probe from a raw file_exists() to validate_plugin(),
which adds path traversal protection and confirms the file is a
recognised plugin (not just any file at that path). Restores the
require_once for wp-admin/includes/plugin.php that this function needs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Default plugin is_active to __return_true

Align with WordPress core, which sets is_active to '__return_true' when
omitted at registration. This lets the rendering site call is_active
unconditionally instead of branching on whether it was provided.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Align phpstan type with stored connector shape

After the registry now always initializes `plugin` and defaults
`is_active` to `__return_true`, mark `plugin` as required and
`file` as optional in the @phpstan-type so static analysis matches
what `register()` actually returns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: peterwilsoncc <peterwilsoncc@git.wordpress.org>
Co-authored-by: mukeshpanchal27 <mukesh27@git.wordpress.org>
Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org>
Co-authored-by: westonruter <westonruter@git.wordpress.org>
peterwilsoncc pushed a commit to peterwilsoncc/gutenberg-build that referenced this pull request May 7, 2026
…7897)

* Connectors: Add is_active callback support to plugin registration

Backports the WP Core changes from WordPress/wordpress-develop#11565
so that AI provider connectors (and Akismet) report the correct plugin
status. Without an explicit `is_active` callback the registry's new
`__return_true` default made every pre-registered connector appear active
even when the underlying plugin was not installed, so the Connectors
screen showed a "Set up" button instead of "Install" whenever Gutenberg
was active.

- Mirror the registry's `__return_true` default and the simplified
  is_installed/is_activated derivation in the script module data.
- Wire AI providers to `$ai_registry->hasProvider( $id )` so their
  status reflects whether the provider plugin is actually available.
- Set Akismet's `is_active` to `is_plugin_active( 'akismet/akismet.php' )`
  since Gutenberg pre-registers it (Core does not), and the new default
  would otherwise mark it as always installed.

* Connectors: Show Akismet with Install button when not installed

The previous client-side workaround hid Akismet entirely whenever the
plugin was not installed, because the server could not report Akismet's
install status reliably. With the new `is_active` callback wired up on
the server side, `isInstalled` is now accurate, so Akismet can be
rendered like any other default connector and offer an Install button
when the plugin is missing.

* Connectors: Restore E2E coverage for Akismet Install button

Re-adds the test that was removed when Akismet was hidden client-side
in #76962. Now that the server reports Akismet's install status
correctly and the JS hide logic is gone, the screen should render the
Akismet card with an Install button when the plugin is not installed —
make sure that's covered.

* Connectors: Update E2E test to expect Install button label

* Connectors: Drop default is_active fallback in registry

All pre-registered connectors now supply their own `is_active` callback,
so the `__return_true` default is no longer needed. Removing it aligns
the registry with the upstream WP Core PR and avoids silently masking
connectors that forget to declare an `is_active` callback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Guard against missing is_active in script module data

Now that the registry no longer injects a default `__return_true` for
`is_active`, a connector registered with a `plugin.file` but without an
`is_active` callback would trigger an undefined-index warning. Treat
that case as active on the assumption the plugin only registers the
connector when it is loaded.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Detect Akismet via AKISMET_VERSION constant

Switch the Akismet `is_active` callback from `is_plugin_active()` to a
`defined( 'AKISMET_VERSION' )` check so it does not have to load
`wp-admin/includes/plugin.php`. This keeps the callback safe to invoke
in non-admin requests where pulling in the admin plugin helpers would
be unnecessary overhead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ADd backport changelog

* Connectors: Remove outdated is_active default from docblock

The default `__return_true` fallback was dropped from the registry, but
the docblock still advertised it. Remove the stale line so callers do
not assume a default exists.

* Connectors: Restore Akismet hide-when-not-installed special case

Bring back the JS-side guard that hides Akismet when the plugin is not
installed. Akismet is bundled with WordPress and the product decision
is to keep it out of the connectors list when missing — other connectors
remain visible because plugins like Woo or SEO suites benefit from the
auto-install/activate flow for their own third-party integrations.

Also drop the E2E test that asserted the inverse (Install button visible
for Akismet), since it conflicts with the restored behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Document default is_active behavior in docblock

When the is_active callback is omitted and a file is provided, the
connector is treated as active under the assumption that the plugin
must be loaded in order to register itself. Spell that out so callers
do not mistake the omission for a no-op.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Use validate_plugin() to detect installed plugin file

Switch the install probe from a raw file_exists() to validate_plugin(),
which adds path traversal protection and confirms the file is a
recognised plugin (not just any file at that path). Restores the
require_once for wp-admin/includes/plugin.php that this function needs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Default plugin is_active to __return_true

Align with WordPress core, which sets is_active to '__return_true' when
omitted at registration. This lets the rendering site call is_active
unconditionally instead of branching on whether it was provided.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Align phpstan type with stored connector shape

After the registry now always initializes `plugin` and defaults
`is_active` to `__return_true`, mark `plugin` as required and
`file` as optional in the @phpstan-type so static analysis matches
what `register()` actually returns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: peterwilsoncc <peterwilsoncc@git.wordpress.org>
Co-authored-by: mukeshpanchal27 <mukesh27@git.wordpress.org>
Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org>
Co-authored-by: westonruter <westonruter@git.wordpress.org>

Source: WordPress/gutenberg@ef41f12
peterwilsoncc pushed a commit to peterwilsoncc/gutenberg-build that referenced this pull request May 7, 2026
…7897)

* Connectors: Add is_active callback support to plugin registration

Backports the WP Core changes from WordPress/wordpress-develop#11565
so that AI provider connectors (and Akismet) report the correct plugin
status. Without an explicit `is_active` callback the registry's new
`__return_true` default made every pre-registered connector appear active
even when the underlying plugin was not installed, so the Connectors
screen showed a "Set up" button instead of "Install" whenever Gutenberg
was active.

- Mirror the registry's `__return_true` default and the simplified
  is_installed/is_activated derivation in the script module data.
- Wire AI providers to `$ai_registry->hasProvider( $id )` so their
  status reflects whether the provider plugin is actually available.
- Set Akismet's `is_active` to `is_plugin_active( 'akismet/akismet.php' )`
  since Gutenberg pre-registers it (Core does not), and the new default
  would otherwise mark it as always installed.

* Connectors: Show Akismet with Install button when not installed

The previous client-side workaround hid Akismet entirely whenever the
plugin was not installed, because the server could not report Akismet's
install status reliably. With the new `is_active` callback wired up on
the server side, `isInstalled` is now accurate, so Akismet can be
rendered like any other default connector and offer an Install button
when the plugin is missing.

* Connectors: Restore E2E coverage for Akismet Install button

Re-adds the test that was removed when Akismet was hidden client-side
in #76962. Now that the server reports Akismet's install status
correctly and the JS hide logic is gone, the screen should render the
Akismet card with an Install button when the plugin is not installed —
make sure that's covered.

* Connectors: Update E2E test to expect Install button label

* Connectors: Drop default is_active fallback in registry

All pre-registered connectors now supply their own `is_active` callback,
so the `__return_true` default is no longer needed. Removing it aligns
the registry with the upstream WP Core PR and avoids silently masking
connectors that forget to declare an `is_active` callback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Guard against missing is_active in script module data

Now that the registry no longer injects a default `__return_true` for
`is_active`, a connector registered with a `plugin.file` but without an
`is_active` callback would trigger an undefined-index warning. Treat
that case as active on the assumption the plugin only registers the
connector when it is loaded.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Detect Akismet via AKISMET_VERSION constant

Switch the Akismet `is_active` callback from `is_plugin_active()` to a
`defined( 'AKISMET_VERSION' )` check so it does not have to load
`wp-admin/includes/plugin.php`. This keeps the callback safe to invoke
in non-admin requests where pulling in the admin plugin helpers would
be unnecessary overhead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ADd backport changelog

* Connectors: Remove outdated is_active default from docblock

The default `__return_true` fallback was dropped from the registry, but
the docblock still advertised it. Remove the stale line so callers do
not assume a default exists.

* Connectors: Restore Akismet hide-when-not-installed special case

Bring back the JS-side guard that hides Akismet when the plugin is not
installed. Akismet is bundled with WordPress and the product decision
is to keep it out of the connectors list when missing — other connectors
remain visible because plugins like Woo or SEO suites benefit from the
auto-install/activate flow for their own third-party integrations.

Also drop the E2E test that asserted the inverse (Install button visible
for Akismet), since it conflicts with the restored behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Document default is_active behavior in docblock

When the is_active callback is omitted and a file is provided, the
connector is treated as active under the assumption that the plugin
must be loaded in order to register itself. Spell that out so callers
do not mistake the omission for a no-op.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Use validate_plugin() to detect installed plugin file

Switch the install probe from a raw file_exists() to validate_plugin(),
which adds path traversal protection and confirms the file is a
recognised plugin (not just any file at that path). Restores the
require_once for wp-admin/includes/plugin.php that this function needs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Default plugin is_active to __return_true

Align with WordPress core, which sets is_active to '__return_true' when
omitted at registration. This lets the rendering site call is_active
unconditionally instead of branching on whether it was provided.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Connectors: Align phpstan type with stored connector shape

After the registry now always initializes `plugin` and defaults
`is_active` to `__return_true`, mark `plugin` as required and
`file` as optional in the @phpstan-type so static analysis matches
what `register()` actually returns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: peterwilsoncc <peterwilsoncc@git.wordpress.org>
Co-authored-by: mukeshpanchal27 <mukesh27@git.wordpress.org>
Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org>
Co-authored-by: westonruter <westonruter@git.wordpress.org>

Source: WordPress/gutenberg@051e6c3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants